using System;
using System.Collections.Generic;
using System.Text;
using FlickrNet;
using System.IO;
using System.Threading;
using System.Diagnostics;
using WhsPhotoUpload.Helpers;
namespace WhsPhotoUpload.Uploader
{
    class Program
    {
        static void Main(string[] args)
        {
            //Creation of EventLog 
            EventLog EventLog1 = new EventLog();

            if (!System.Diagnostics.EventLog.SourceExists("FlickrUpload"))
                System.Diagnostics.EventLog.CreateEventSource(
                   "FlickrUpload", "Application");

            EventLog1.Source = "FlickrUpload";

            //Application Variable
            string apikey = String.Empty;
            string sharedsecret = String.Empty;
            string photopickupfolder = String.Empty;
            string photofinishedfolder = String.Empty;

            EventLog1.WriteEntry("Flickr Uploader is started.", EventLogEntryType.Information);
            ActivityLogTableAdapters.ActivityLogTableAdapter adapter = new WhsPhotoUpload.Uploader.ActivityLogTableAdapters.ActivityLogTableAdapter();
            string tempFrob;
            try
            {
                //Retriving Application Settings from Registry
                apikey=RegistryTools.GetAppSetting(RegistryTools.WhsPhotoUploadSettings.FlickrApplicationKey);
                sharedsecret = RegistryTools.GetAppSetting(RegistryTools.WhsPhotoUploadSettings.FlickrSharedSecret);
                photopickupfolder = RegistryTools.GetAppSetting(RegistryTools.WhsPhotoUploadSettings.PhotoPickupFolder);
                photofinishedfolder = RegistryTools.GetAppSetting(RegistryTools.WhsPhotoUploadSettings.PhotoFinishedFolder);

                Console.WriteLine("API Key: " + apikey);
                Console.WriteLine("\nShared Secret: " + sharedsecret);
                Console.WriteLine("\nPhotoPickup: " + photopickupfolder);
                Console.WriteLine("\nPhotoFinish: " + photofinishedfolder + "\n");
            }
            catch (Exception ex)
            {
                adapter.Insert(DateTime.Now, "Uploader", "An error occured while retriving your registry settings. Exception: "+ex.ToString(), DateTime.Now);
            }

            //Application Variable
            int uploadcount = 0;
            Auth auth;
            string photoid = String.Empty;
            string psetid = String.Empty;
            Flickr flickr;
            Console.WriteLine("Starting Flickr Uploader\n");

            
            adapter.Insert(DateTime.Now, "Uploader", "Flickr Uploader is started.", DateTime.Now);
            //perform authorization
            flickr = new Flickr(apikey, sharedsecret);
            //set the auth token
            try
            {
                if (RegistryTools.GetAppSetting(RegistryTools.WhsPhotoUploadSettings.FlickrToken) == "")
                {
                    //No token found; unable to link to flickr account
                    EventLog1.WriteEntry("Invalid link between flickr account", EventLogEntryType.Error);
                    Console.Write("Your link to flickr is not found. Please re-link your account with flickr.");
                    adapter.Insert(DateTime.Now, "Uploader", "Your link to flickr is not found. Please re-link your account with flickr.", DateTime.Now);
                    return;             
                }
                else
                {
                    //Token found; link successful
                    Console.Write("Using existing token\n");
                    flickr.AuthToken = RegistryTools.GetAppSetting(RegistryTools.WhsPhotoUploadSettings.FlickrToken);
                }
            }
            catch (FlickrException ex)
            {
                //Flickr Authentication Failed
                EventLog1.WriteEntry("Flickr is unable to to authenticate you. Exception: "+ex.ToString(), EventLogEntryType.Error);
                Console.WriteLine("Flickr did not authenticate you: " + ex.ToString());
                Console.WriteLine("FlickrException: " + ex.ToString());
                adapter.Insert(DateTime.Now, "Uploader", "Flickr is unable to authenticate you. Exception: "+ex.ToString(), DateTime.Now);
                Console.WriteLine("Tries to get a new token");

                //Try to authenticate and relink once more
                tempFrob = flickr.AuthGetFrob();
                string flickrUrl = flickr.AuthCalcUrl(tempFrob, AuthLevel.Write);
                System.Diagnostics.Process.Start(flickrUrl);
                Thread.Sleep(5000);
                auth = flickr.AuthGetToken(tempFrob);
                flickr.AuthToken = auth.Token;
                Console.Write(flickr.AuthToken);
            }

            //start looking into folder
            //if it's a file lying in the root folder (no sets assigned)
            foreach (string filename in Directory.GetFiles(photopickupfolder, "*.jpg"))
            {
                //random unassigned photos                 
                //upload random photo
                try
                {
                    flickr.UploadPicture(filename, Path.GetFileNameWithoutExtension(filename));
                    Console.WriteLine("Sending File: " + Convert.ToString(uploadcount + 1) + "\n");
                    adapter.Insert(DateTime.Now, "Uploader", "Sending File: " + filename + " is successful.", DateTime.Now);
                    uploadcount++;
                }
                catch (Exception ex)
                {
                    adapter.Insert(DateTime.Now, "Uploader", "An error occured while uploading the photo. Exception: " + ex.ToString(), DateTime.Now);
                }

                //check if the filename exist in the backup folder
                if (File.Exists(photofinishedfolder + Path.GetFileName(filename)))
                {
                    //delete file if it there's a file in backup with the same name
                    File.Delete(photofinishedfolder + Path.GetFileName(filename));
                }

                //move the random photo to the backup folder
                File.Move(photopickupfolder + Path.GetFileName(filename), photofinishedfolder + Path.GetFileName(filename));

                //random file uploaded complete
            }

            foreach (string dirname in Directory.GetDirectories(photopickupfolder))
            {
                //it's a folder
                bool firstphoto = true;
                string foldername = Path.GetFileName(dirname);
                //create backup directory
                Directory.CreateDirectory(photofinishedfolder + foldername);

                foreach (String f in Directory.GetFiles(photopickupfolder + foldername))
                {
                    if (Path.GetExtension(f) == ".jpg")
                    {
                        //upload the picture
                        try
                        {
                            photoid = flickr.UploadPicture(f, Path.GetFileNameWithoutExtension(f));
                            adapter.Insert(DateTime.Now, "Uploader", "Sending File: "+f+" is successful.", DateTime.Now);
                        }
                        catch (Exception ex)
                        {
                            EventLog1.WriteEntry("A problem occured while uploading the photos. Exception: "+ex.ToString(), EventLogEntryType.Error);
                            adapter.Insert(DateTime.Now, "Uploader", "An error occured while uploading the photo. Exception: " + ex.ToString(), DateTime.Now);
                        }
                        if (firstphoto == false)
                        {
                            //first photo created
                            //photoset created
                            //add photo to photoset
                            try
                            {
                                flickr.PhotosetsAddPhoto(psetid, photoid);
                            }
                            catch (Exception ex)
                            {
                                EventLog1.WriteEntry("Unable to create photoset. Please check your flickr limit. Exception: "+ex.ToString(), EventLogEntryType.Error);
                                adapter.Insert(DateTime.Now, "Uploader", "Unable to create photoset. Please check your flickr limit. Exception: " + ex.ToString(), DateTime.Now);
                            }
                            
                        }
                        if (firstphoto)
                        {
                            //if this is the first photo
                            //create the photoset and assign first photo to photoset primary photo
                            Photoset pset = flickr.PhotosetsCreate(foldername, photoid);
                            EventLog1.WriteEntry("PhotoSet: " + foldername + " is created", EventLogEntryType.Information);
                            adapter.Insert(DateTime.Now, "Uploader", "PhotoSet: " + foldername + " is created", DateTime.Now);
                            Console.WriteLine("Created Photoset: " + foldername);
                            psetid = pset.PhotosetId;
                            //first photo is added
                            firstphoto = false;
                        }

                    }
                    
                    try
                    {
                        File.Delete(photofinishedfolder + foldername + "\\" + Path.GetFileName(f));
                        //move file to backup
                        File.Move(photopickupfolder + foldername + @"\" + Path.GetFileName(f), photofinishedfolder + foldername + @"\" + Path.GetFileName(f));
                        
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.ToString());
                    }                    
                }

                System.IO.File.SetAttributes(photopickupfolder + foldername + "\\", System.IO.FileAttributes.Normal);
                Directory.Delete(photopickupfolder + foldername + "\\");
                
            }
            adapter.Insert(DateTime.Now, "Uploader", "Uploading completed. " + uploadcount.ToString() + " pictures are uploaded successfully.", DateTime.Now);
            EventLog1.WriteEntry("Uploading Completed: " + uploadcount.ToString() + " pictures has been uploaded", EventLogEntryType.Information);    
        }        
    }
}
